package com.atguigu.lease.common.utils;

import com.atguigu.lease.common.exception.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.util.Date;

public class JwtUtil {

    // Token 有效时长：1小时（60分钟，以毫秒为单位）
    private static long tokenExpiration = 60 * 60 * 1000L;

    // 用于签名 JWT 的密钥，通过 HMAC-SHA 算法生成
    private static SecretKey tokenSignKey = Keys.hmacShaKeyFor("M0PKKI6pYGVWWfDZw90a0lTpGYX1d4AQ".getBytes());

    /**
     * 创建 JWT Token
     * @param userId 用户 ID（用于标识用户）
     * @param username 用户名（用于附加用户信息）
     * @return 生成的 JWT Token 字符串
     */
    public static String createToken(Long userId, String username) {
        // 使用 JJWT 库创建一个 JWT Token
        String token = Jwts.builder()
                .setSubject("USER_INFO") // 设置主题（此处表示用户信息）
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)) // 设置过期时间
                .claim("userId", userId) // 自定义声明，存储用户 ID
                .claim("username", username) // 自定义声明，存储用户名
                .signWith(tokenSignKey) // 使用密钥进行签名，确保 Token 的合法性
                .compressWith(CompressionCodecs.GZIP) // 使用 GZIP 对 Token 进行压缩
                .compact(); // 生成最终的 Token 字符串
        return token;
    }

    /**
     * 解析 JWT Token
     * @param token 客户端传递的 JWT Token
     * @return Claims 对象，包含 Token 的内容
     * @throws LeaseException 如果 Token 过期或无效时抛出自定义异常
     */
    public static Claims parseToken(String token) {
        try {
            // 解析 Token
            Jws<Claims> claimsJws = Jwts.parserBuilder()
                    .setSigningKey(tokenSignKey) // 设置签名密钥，用于校验 Token 的合法性
                    .build()
                    .parseClaimsJws(token); // 解析 Token
            return claimsJws.getBody(); // 获取解析后的内容（Claims 对象）

        } catch (ExpiredJwtException e) {
            // 捕获 Token 过期异常，抛出自定义异常
            throw new LeaseException(ResultCodeEnum.TOKEN_EXPIRED);
        } catch (JwtException e) {
            // 捕获其他 JWT 相关异常（如非法 Token），抛出自定义异常
            throw new LeaseException(ResultCodeEnum.TOKEN_INVALID);
        }
    }
}
